
#include <QSettings>
#include "chanwatcher.h"
#include "chanmanager.h"
#include "components/chan.h"
#include "components/board.h"
#include "mainwindow.h"
#include "mainwindowcontroller.h"

namespace Wishmaster
{
	class SwapThread : public QThread
	{
	public:
		SwapThread(ChanManager* manager, QObject* parent = 0) : QThread(parent), m_manager(manager)
		{
		}

		virtual void run()
		{
			if(m_running)
				return;
			m_running = true;
			try
			{
				log(llDebug, "Swapping");
				setPriority(QThread::LowestPriority);
				m_manager->swap();
			}
			catch(...)
			{
			}
			m_running = false;
		}
		
	private:
		ChanManager* m_manager;
		bool m_running;
	};

	ChanWatcher::ChanWatcher() : m_manager(NULL),
		m_view(NULL)
	{
	}

	ChanWatcher::~ChanWatcher()
	{
	}

	bool ChanWatcher::startTimers()
	{
		if(!m_view)
			return false;
		if(!m_manager)
			return false;
		m_swapThread = new SwapThread(m_manager);
		m_swapTimer.setInterval(20000);
		m_swapTimer.start();
		connect(&m_swapTimer, SIGNAL(timeout()), m_swapThread, SLOT(start()));

		QSettings settings;
		m_watchTimer.stop();
		m_watchTimer.start(1000 * settings.value("watch/interval", 60).toInt());
		connect(&m_watchTimer, SIGNAL(timeout()), this, SLOT(watchRefresh()));

		m_autoRefreshTimer.start(1000 * settings.value("autorefresh/interval", 60).toUInt());
		connect(&m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(autoRefresh()));

		return true;
	}

	void ChanWatcher::setView(MainWindow* view)
	{
		m_view = view;
	}

	void ChanWatcher::setManager(ChanManager* manager)
	{
		m_manager = manager;
	}

	void ChanWatcher::autoRefresh()
	{
		QSettings settings;
		int policynum = settings.value("autorefresh/policy", 2).toUInt();
		bool indexOnly = settings.value("autorefresh/indexonly", false).toBool();
		log(llDebug, "autoRefresh: indexonly: %d", indexOnly);
		switch(policynum)
		{
			case rpAllChans:
			{
				refreshAllChans(false);
			}
			case rpCurrentChan:
			{
				if(m_view->controller()->activeChan())
					refreshChan(m_view->controller()->activeChan(), false);
				break;
			}
			case rpCurrentBoard:
			{
				if(m_view->controller()->activeBoard())
					refreshBoard(m_view->controller()->activeBoard());
				break;
			}
			case rpNothing:
			default:
				// Do nothing
				break;
		}

		emit statusMessage("Autorefresh started", 5000);
		m_manager->collectGarbage();
	}

	void ChanWatcher::refreshAllChans(bool ignoreOverrides)
	{
		ChanList* chanlist = m_manager->chanlist();
		for(int chanNum = 0; chanNum < chanlist->chansCount(); chanNum++)
		{
			Chan* chan = chanlist->getChan(chanNum);
			refreshChan(chan, ignoreOverrides);
		}
	}

	void ChanWatcher::refreshChan(Chan* chan,bool ignoreOverrides)
	{
		for(int boardIndex = 0; boardIndex < chan->boardsCount(); boardIndex++)
		{
			Board* board = chan->board(boardIndex);
			if(ignoreOverrides)
			{
				refreshBoard(board);
			}
			else
			{
				if(board->property("donotrefresh").toBool())
					continue;
				if(!board->property("override").toBool())
					refreshBoard(board);
			}
		}
	}

	void ChanWatcher::refreshBoard(Board* board)
	{
		m_manager->requestBoardIndex(board->getParent()->name(), board->name());
	}

	void ChanWatcher::watchRefresh()
	{
		m_view->refreshTabs();
		foreach(const ThreadId& id, m_watchList)
		{
			m_manager->requestThread(id);
		}
	}

	void ChanWatcher::addToWatchList(const ThreadId& threadId)
	{
		if(!m_watchList.contains(threadId))
			m_watchList.append(threadId);
	}

	void ChanWatcher::removeFromWatchList(const ThreadId& threadId)
	{
		m_watchList.removeOne(threadId);
	}

	QList<ThreadId> ChanWatcher::watchList() const
	{
		return m_watchList;
	}
}

